package com.yonyou.brigade.util.operateutil;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.util.StringUtils;

import java.text.*;
import java.util.Date;

/**
 *
 * @author jiangshjk
 * @since 2018-06-09
 */
public class JsonUtils {

    private static ObjectMapper om = new ObjectMapper();

    /** 初始化 om*/
    static {
        om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

        //设置日期格式
        om.setDateFormat(new GenericDateFormat());
    }

    /**
     * 将对象转成字符串
     * @param object
     * @return
     */
    public static String object2JsonStr(Object object) {
        String jsonStr = null;
        try {
            jsonStr = om.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonStr;
    }

    /**
     * json字符串转对象
     * 注意：此种方法解决不了泛型擦除问题
     * @param json
     * @param c
     * @param <T>
     * @return
     */
    public static <T> T jsonStr2Object(String json, Class<T> c) {
        try {
            return om.readValue(json,c);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 此方法可以解决泛型擦除问题
     * @param json
     * @param reference
     * @param <T>
     * @return
     */
    public static <T> T jsonStr2Object(String json, TypeReference<T> reference) {
        try {
            return om.readValue(json,reference);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 判断是否能转成JSONObject类型
     * @param json
     * @return
     */
    public static boolean isJSONObject(String json) {
        if (StringUtils.isEmpty(json)) {
            return false;
        }
        try {
            JSONObject.parseObject(json);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否能转成JSONArray类型
     * @param json
     * @return
     */
    public static boolean isJSONArray(String json) {
        if (StringUtils.isEmpty(json)) {
            return false;
        }
        try {
            JSONArray.parseArray(json);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 定义日期格式化
     */
    public static class GenericDateFormat extends DateFormat {

        /** 默认日期样式 */
        private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";

        /** 当前使用的日期样式 */
        private String datePattern = DEFAULT_DATE_PATTERN;

        /** 支持的日期样式 */
        public static final String[] DATE_PATTERNS = new String[] {"yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss", "yyyy-MM-dd", "yyyyMMdd", "yyyy/MM/dd",  "yyyy-MM", "yyyyMM", "yyyy/MM","yyyy"};

        public GenericDateFormat() {

        }

        public GenericDateFormat(String datePattern) {
            this.datePattern = datePattern;
        }

        @Override
        public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
            return new SimpleDateFormat(datePattern).format(date, toAppendTo, fieldPosition);
        }

        @Override
        public Date parse(String source, ParsePosition pos) {
            Date date = null;
            for(String datePattern : DATE_PATTERNS) {
                try {
                    date = new SimpleDateFormat(datePattern).parse(source, pos);
                    break;
                }catch (Exception e) {

                }
            }
            return date;
        }

        // 主要还是装饰这个方法
        @Override
        public Date parse(String source) throws ParseException {
            Date date = null;
            for(String datePattern : DATE_PATTERNS) {
                try {
                    date = new SimpleDateFormat(datePattern).parse(source);
                    break;
                }catch (Exception e) {

                }
            }
            return date;
        }

        // 这里装饰clone方法的原因是因为clone方法在jackson中也有用到
        @Override
        public Object clone() {
            return new GenericDateFormat();
        }
    }

}
